/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MSDP_SPATIAL_COMMON_H
#define MSDP_SPATIAL_COMMON_H

#include <map>
#include <math.h>
#include <string>
#include <time.h>
#include <vector>
#include "constants.h"
#include "msdp_algorithm_common.h"

namespace OHOS {
namespace Msdp {
class DeviceInfo {
public:
    DeviceInfo() = default;
    DeviceInfo(const SpatialDevice& device)
    {
        deviceId = device.deviceId;
        typeId = device.typeId;
        networkId = device.networkId;
    };
    ~DeviceInfo() = default;

    bool operator==(const DeviceInfo& device) const
    {
        return (deviceId == device.deviceId);
    };
    bool operator<(const DeviceInfo& device) const
    {
        return (deviceId < device.deviceId);
    };
    bool Equal(const SpatialDevice& device) const
    {
        return (deviceId == device.deviceId);
    };
    bool IsRichDevice() const
    {
        if (typeId == 0) {
            // To be added
        }
        return true;
    };
    SpatialDevice ToSpatialDevice() const
    {
        SpatialDevice sd;
        sd.deviceId = deviceId;
        sd.typeId = typeId;
        sd.networkId = networkId;
        sd.deviceName = deviceName;
        return sd;
    }

    std::string deviceId {""};
    uint32_t typeId {0};
    std::string networkId {""};
    std::string deviceName {""};
};

class DeviceCoordinate {
public:
    DeviceCoordinate() = default;
    DeviceCoordinate(const SpatialEvent& event, float orientation = 0)
    {
        distance = event.distance;
        angle = event.angle + orientation;
        if (angle > PERIGON) {
            angle = angle - PERIGON;
        } else if (angle < 0) {
            angle = angle + PERIGON;
        }
        direction = event.direction;
        if (event.IsExact()) {
            exact = true;
            x = distance * cos(angle);
            y = distance * sin(angle);
        };
        updateTime = time(0);
        keepingTime = 0;
        innerouter = event.innerOuter;
        exist = event.exist;
    };
    ~DeviceCoordinate() = default;

    float distance {0.0f};
    float angle {0.0f};
    uint32_t direction {SpatialDirection::INVALID};
    bool exact {false};
    float x {0.0f};
    float y {0.0f};
    int innerouter {-1};
    int exist {-1};
    time_t updateTime {0};
    time_t keepingTime {0};
};

class SpatialMap {
public:
    SpatialMap() = default;
    SpatialMap(const SpatialMap& obj)
    {
        center = obj.center;
        map = obj.map;
        top = obj.top;
        committed = obj.committed;
        commitTime = obj.commitTime;
        updateTime = obj.updateTime;
        history = obj.history;
    };
    ~SpatialMap() = default;
    bool operator==(const SpatialMap& map) const
    {
        return (committed && top == map.top);
    };
    DeviceInfo center;
    std::map<DeviceInfo, DeviceCoordinate> map;
    uint32_t top;
    bool committed {true};
    time_t commitTime;
    time_t updateTime;
    std::map<uint32_t, time_t> history;
};
} // namespace Msdp
} // namespace OHOS
#endif // MSDP_SPATIAL_COMMON_H
